package com.calvin.study.multithread.threadutils;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;

import com.calvin.study.utils.Print;
import com.calvin.study.utils.ThreadUtil;


//CountDownLatch：一个或者多个线程，等待另外 N 个线程完成某个事情之后才能执行。
//CountDownLatch 就像玩王者农药开局的加载一样，所有人要等待其他人都加载 100% 之后才能开始游戏。
public class CountDownLatchDemo {

	public static void main(String[] args) throws InterruptedException {
		//testCountDownLatch01();
		testCountDownLatch02();
	}

	public static void testCountDownLatch01() throws InterruptedException {
		CountDownLatch count = new CountDownLatch(6);
		for (int i = 1, len = 6; i <= len; i++) {
			new Thread(() -> {
				System.out.println("[ 线程" + Thread.currentThread().getName() + "] \t" + "上完自习");
				count.countDown();// 减少锁存器的计数
			}, String.valueOf(i)).start();
		}
		// 直到CountDownLatch(6)计数器中的线程都运行结束后（即锁存器计数到零），释放所有等待线程
		count.await();
		System.out.println(Thread.currentThread().getName() + "\t班长锁门离开教室");
	}

	private static final int seat = 20;

	public static void testCountDownLatch02() throws InterruptedException {
		CountDownLatch count = new CountDownLatch(seat);
		// 取得CPU密集型线程池
		Executor e = ThreadUtil.getCpuIntenseTargetThreadPool();
		for (int i = 1, len = seat; i < len; i++) {
			e.execute(new Person(count, i));
		}
		count.await();
		Print.tcfo("人到齐， 开车");
		
	}

	static class Person implements Runnable {

		private final CountDownLatch count;
		private final int i;

		Person(CountDownLatch count, int i) {
			this.count = count;
			this.i = i;
		}

		@Override
		public void run() {
			try {
				// 报数
				Print.tcfo("第" + i + "个人已到");
				count.countDown(); // step3： 倒数闩减少1
			} catch (Exception ex) {

			}
		}
	}
}
